<?php
/**
 * Возвращает безопасную для сохранения в БД строку (в том числе преобразовывает и теги)
 *
 * @param string $toBeEscaped - строка, которую следует сделать безопасной
 * @return string - безопасная строка
 */
function absolutelyEscapeString($toBeEscaped){
  if (!get_magic_quotes_gpc() && !get_magic_quotes_runtime()){
  	$toBeEscaped = mysql_escape_string(htmlspecialchars($toBeEscaped));
  	$toBeEscaped = stripslashes(str_replace(array('"', "'"), array('&quot;', "&#039;"), $toBeEscaped));
    return $toBeEscaped;
  }
  else{
  	$toBeEscaped = htmlspecialchars($toBeEscaped);
  	$toBeEscaped = stripslashes(str_replace(array('"', "'"), array('&quot;', "&#039;"), $toBeEscaped));
    return $toBeEscaped;
  }
}

/**
 * Возвращает безопасную для сохранения в БД строку (без преобразования тегов)
 *
 * @param string $toBeEscaped - строка, которую следует сделать безопасной
 * @return string - безопасная строка
 */
function absolutelyEscapeStringSavingHtml($toBeEscaped){
  if (!get_magic_quotes_gpc() && !get_magic_quotes_runtime())
    return mysql_escape_string($toBeEscaped);
  else
    return $toBeEscaped;//addslashes($toBeEscaped);
}

/**
 * Возвращает безопасную для сохранения в БД строку (с учетом обработки WYSYWYG редактором)
 *
 * @param string $toBeEscaped - строка, которую следует сделать безопасной
 * @return string - безопасная строка
 */
function absolutelyEscapeStringFromWysiwyg($toBeEscaped, $type = "admin"){
    return absolutelyEscapeStringSavingHtml( Service_Editor::parseHTML($toBeEscaped, $type) );
}


/**
 * Обрабочтчик непойманных исключений
 * Выводит информацию о необработанных исключениях
 *
 * @param Exception $exception - необработанное исключение
 */
function exceptionHandler(Exception $exception){
  echo '<div class="programmError">';
  echo '<strong>Не пойманное исключение</strong><br />';
    echo 'Сообщение: ' . $exception->getMessage() . '<br />';
    echo 'Файл: <strong>' . $exception->getFile() . '</strong>, строка <strong>' . $exception->getLine() . '</strong><br />';
    $arrExceptionTrace = $exception->getTrace();
    if(sizeof($arrExceptionTrace)){
      echo 'Цепочка:<br />';
      for ($i = 0; $i < sizeof($arrExceptionTrace); $i++) {
        echo '&nbsp;&nbsp;&nbsp;&nbsp;<strong>' . $arrExceptionTrace[$i]['file'] . '</strong>, строка <strong>' . $arrExceptionTrace[$i]['line'] . '</strong>, функция <strong>' . $arrExceptionTrace[$i]['function'] . '</strong>(';
        for ($j = 0; $j < sizeof($arrExceptionTrace[$i]['args']); $j++) {
        	if($j != 0)
        	  echo ', ';
        	echo $arrExceptionTrace[$i]['args'][$j];
        }
        echo ')<br />';
      }
    }
  echo '</div><br />';
}

function exceptionHandler2(Exception $exception){
}

/**
 * Обработчик ошибок, предупреждений и пр.
 * Выводит информацию о всевозможных ошибках
 *
 * @param integer $errType
 * @param string $errMsg
 * @param string $errFile
 * @param integer $errLine
 * @param array $errContext
 */
function errorHandler($errType, $errMsg, $errFile, $errLine, $errContext) {
  switch ($errType) {
    //E_ERROR, E_PARSE, E_CORE_ERROR, E_CORE_WARNING, E_COMPILE_ERROR, E_COMPILE_WARNING - эти ошибки нельзя обработать
    case E_WARNING: case E_NOTICE: case E_CORE_WARNING: case E_USER_ERROR: case E_USER_WARNING: case E_USER_NOTICE: //Выводим все важные предупреждения в браузер, в лог-файл
    echo '<div class="programmError">';
  	  echo '<strong>' . getExcteptionTypeName($errType) . '</strong><br />';
    echo 'Сообщение: ' . $errMsg . '<br />';
    echo 'Файл: <strong>' . $errFile . '</strong>, строка <strong>' . $errLine . '</strong><br />';
	  echo '</div><br />';
	  case (E_NOTICE | E_USER_NOTICE):
    default: //Выводим определенные и оставшиеся ошибки в лог-файл
    	$logMsg = date("Y-m-d H:i:s") . ' Ошибка ' . $errType . ' в файле ' . $errFile . ' (' . $errLine . '): ' . $errMsg . "\n";
	    $logErrType = 3;
      error_log($logMsg, $logErrType, LOG);
	}
}

function errorHandler2($errType, $errMsg, $errFile, $errLine, $errContext){

}

/**
 * Выдает текстовое представление типа ошибки по его числовому эквиваленту
 *
 * @param integer $errType - числовой тип ошибки
 * @return string - строковый тип ошибки
 */
function getExcteptionTypeName($errType){
  switch ($errType){
    case 1: return 'FATAL ERROR';
    case 2: return 'WARNING';
    case 4: return 'PARSE';
    case 8: return 'NOTICE';
    case 16: return 'CORE_ERROR';
    case 32: return 'CORE_WARNING';
    case 64: return 'COMPILE_ERROR';
    case 128: return 'COMPILE_WARNING';
    case 256: return 'USER_ERROR';
    case 512: return 'USER_WARNING';
    case 1024: return 'USER_NOTICE';
    case 2048: return 'STRICT';
  }
}

/**
 * Из двух массивов формируем новый, содержащий элементы первого массива, которых нет во втором массиве
 *
 * @param array $arr1
 * @param array $arr2
 * @return array
 */
function arrayFullDifference($arr1, $arr2, $strictLowerCase = false) {
  if (empty($arr2))
    return $arr1;
  $arrNotExists = array();
  foreach ($arr1 as $arr1Element) {
    $isArr1ElemInArr2 = false;
    if ($strictLowerCase) {
      if (!in_iarray($arr1Element, $arr2))
        $arrNotExists[] = $arr1Element;
    }
    else {
      if (!in_array($arr1Element, $arr2))
        $arrNotExists[] = $arr1Element;
    }
  }
  return $arrNotExists;
}

function in_iarray($val, $arr) {
  $arrSize = sizeof($arr);
  for ($i = 0; $i < $arrSize; $i++)
    if (strtolowerU($val) == strtolowerU($arr[$i]))
      return true;
  return false;
}

function array_iunique($arr){
  $n = array();
  $arrSize = sizeof($arr);
  for ($i = 0; $i < $arrSize; $i++)
    if (!in_iarray($arr[$i], $n))
      $n[] = $arr[$i];
  return $n;
}

/* Converts a string to lowercase */
function strtolowerU($s) {
  return mb_strtolower($s, "utf-8");
}

/* Converts a string to lowercase */
function strtoupperU($s) {
  return mb_strtoupper($s, "utf-8");
}

/**
 * Из двух ассоциативных массивов формируем новый, содержащий элементы первого массива, которых нет во втором массиве
 *
 * @param array $arr1
 * @param array $arr2
 * @param string $strField1 - поле первого ассоциативного массива, по которому производится сравнение
 * @param string $strField2 - поле второго ассоциативного массива, по которому производится сравнение
 * @return array
 */
function getDataArraysFullDiff($arr1, $arr2, $strField1, $strField2) {
  $arrNotExists = array();
  foreach ($arr1 as $arr1Element) {
    $isArr1ElemInArr2 = false;
    foreach ($arr2 as $arr2Element) {
      if ($arr1Element[$strField1] == $arr2Element[$strField2]) {
        $isArr1ElemInArr2 = true;
        break;
      }
    }
    if (!$isArr1ElemInArr2)
      $arrNotExists[] = $arr1Element;
  }
  return $arrNotExists;
}
/**
 * Возвращаем колонку из двумерного ассоциативного массива
 *
 * @param array $arrSrc
 * @param string/int $key
 * @return array
 */
function getArrayColumn($arrSrc, $key) {
  $arrColumn = array();
  if (empty($arrSrc))
    return $arrColumn;
  foreach ($arrSrc as $arrElement)
    $arrColumn[] = $arrElement[$key];
  return $arrColumn;
}

/**
 *
 *
 * @param unknown_type $arrSrc - входной массив
 * @param unknown_type $strField - основное поле
 * @param unknown_type $arrFields - поля простого массива, из которых нужно сделать массив и вставить в поле $strFieldForArray основного массива
 * @param unknown_type $strFieldForArray - поле, куда вставися массив, состоящий из полей $arrFields
 * @return array - результат
 */
function arrayConvert($arrSrc, $strField, $arrFields, $strFieldForArray){
	if (is_string($arrFields))
		$arrFields[0] = $arrFields;
	$arrSize = sizeof($arrSrc);
	$arrSrcSubArray = array();
	$idCurStrField = 0;
	for ($i = 0; $i < $arrSize; $i++){
		$idCurStrField = $arrSrc[$i][$strField];
		if (!empty($arrSrc[$i][$arrFields[0]])){
			$k = 0;
			foreach ($arrFields as $curField){
				$arrSrcSubArray[$i][$k][$curField] = $arrSrc[$i][$curField];
				unset($arrSrc[$i][$curField]); // удаляем элементы, скопированные в подмассив
			}
			$k++;
			for ($j = $i+1; $j < $arrSize; $j++){
				if (isset($arrSrc[$j][$strField]) && $idCurStrField == $arrSrc[$j][$strField]){
					if (!empty($arrSrc[$j][$arrFields[0]])){
						foreach ($arrFields as $curField){
							$arrSrcSubArray[$i][$k][$curField] = $arrSrc[$j][$curField];
						}
						$k++;
					}
				}
			}
			$arrSrc[$i][$strFieldForArray] = $arrSrcSubArray[$i]; //
		}
	}

	$idCurStrField = 0; // повторяющиеся элементы обнуляем
	for ($i = 0; $i < $arrSize; $i++){
		$idCurStrField = $arrSrc[$i][$strField];
		for ($j = $i+1; $j < $arrSize; $j++){
			if (isset($arrSrc[$j][$strField]) && $idCurStrField == $arrSrc[$j][$strField]){
				$arrSrc[$j] = NULL;
			}
		}
	}

	$arrSrcNew = array(); // убираем пустые элементы
	for ($i = 0; $i < $arrSize; $i++){
		if ($arrSrc[$i] != NULL){
			$arrSrcNew[] = $arrSrc[$i];
		}
	}
	return $arrSrcNew;
}

/**
 * Возвращает значение, закглючённое между тегами <$tag></$tag>, берётся первый тег из всей строки
 *
 * @param string $str
 * @param string $tag
 * @return string
 */
function getTagBetweenValueFirst($str, $tag) {
  $start = strpos($str, $tag);
  $finish = findEndOfTag($str, $tag, $start);
  $str = substr($str, $start - 1, ($finish - $start) + 2);
  $str = substr($str, strpos($str, ">") + 1);
  return substr($str, 0, strlen($str) - strlen('</' . $tag . '>'));
}

/**
 *
 *
 * @param string $htmlString
 * @param string $tagName
 * @param integer $startPosition
 */
function findEndOfTag($htmlString, $tagName, $startPosition, $k = 1) {
	$tagNameLength = strlen($tagName);
	$closePosition = $openPosition = $startPosition;
	for (; $k > 0; $k--) {
		$closePosition = strpos( $htmlString, '</' . $tagName, $closePosition);
		if($closePosition === false)
		  return false;
		$closePosition = strpos( $htmlString, '>', $closePosition);
	}
	while (true) {
		$openPosition = strpos( $htmlString, '<' . $tagName, $openPosition);
		if($openPosition === false)
		  break;
		$openPosition = strpos( $htmlString, '>', $openPosition);
		if($openPosition < $closePosition)
		  $k++;
		else
		  break;
	  if($k == 100)
	    break;
	}
	if($k == 0)
	  return $closePosition;
	else
	  return findEndOfTag($htmlString, $tagName, $closePosition + 1, $k);
}
 /**
 * Функция из массива, например, айдишников, делает строку айдишников через запятую, т.е. 1, 2 , 3, 4
 *
 * @param string $toBeEscaped - строка, которую следует сделать безопасной
 * @return string - безопасная строка
 */
function intEscapeJoin(string $glue, array $arrToBeEscaped) {
 $sizeOfArr = sizeof($arrToBeEscaped);
 if(!$sizeOfArr) return '';
 $retStr= '';
 for ($i=0; $i < $sizeOfArr; $i++) {
  if($i)
    $retStr .= $glue . intval($arrToBeEscaped[$i]);
  else
    $retStr .= intval($arrToBeEscaped[$i]);
 }
 return $retStr;
}

/*Метод получает текущий url*/
function getCurrentUrl() {
	global $QUERY_STRING;
	global $PHP_SELF;
	if ($QUERY_STRING != '')
	  return $PHP_SELF  . '?' . $QUERY_STRING;
	else
		return $PHP_SELF;
}
/*Метод получает текущий малый url*/
function getCurrentSmallUrl() {
	return $_SERVER['PHP_SELF'];
}

//находит ближайший к указанному значению элемент в массиве 
function array_find_closest($value, $array) {
  $size = count($array);
  if ($size > 0) {
    //absolute difference between 0th element and input value
    $diff = abs($array[0] - $value);
    //element closest to input value
    $ret = $array[0];
    //loop through the rest of the array
    for ($i = 1; $i < $size; $i++) {
      $temp = abs($array[$i] - $value);
      if ($temp < $diff) {
        //set new difference and closest element
        $diff = $temp;
        $ret = $array[$i];
      }
    }
    return $ret;
  } else
  return NULL;
}


?>